package com.sleep.psy.external_server.business.main.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sleep.psy.external_server.business.evaluation.service.EvaluationReportService;
import com.sleep.psy.external_server.business.main.entity.*;
import com.sleep.psy.external_server.business.main.entity.dto.SchemeInfo;
import com.sleep.psy.external_server.business.main.entity.dto.Training;
import com.sleep.psy.external_server.business.main.entity.vo.LoginReq;
import com.sleep.psy.external_server.business.main.entity.vo.RegistReq;
import com.sleep.psy.external_server.business.main.entity.vo.UpdateUserReq;
import com.sleep.psy.external_server.business.main.mapper.MainDistributerMapper;
import com.sleep.psy.external_server.business.main.mapper.MainUserMapper;
import com.sleep.psy.external_server.business.main.mapper.MainUserSchemeMapper;
import com.sleep.psy.external_server.business.main.service.MainSchemeService;
import com.sleep.psy.external_server.business.main.service.MainUserSchemeService;
import com.sleep.psy.external_server.business.main.service.MainUserService;
import com.sleep.psy.external_server.business.main.service.MainUserTypeService;
import com.sleep.psy.external_server.business.psy.entity.PsyBaseVideo;
import com.sleep.psy.external_server.business.psy.service.PsyBaseVideoService;
import com.sleep.psy.external_server.business.resourse.entity.ResourseScale;
import com.sleep.psy.external_server.business.resourse.mapper.ResourseScaleMapper;
import com.sleep.psy.external_server.business.resourse.service.ResourseScaleService;
import com.sleep.psy.external_server.business.sys.entity.SysDept;
import com.sleep.psy.external_server.business.sys.service.SysDeptService;
import com.sleep.psy.external_server.constants.MySqlConstant;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sleep.psy.external_server.result.Result;
import com.sleep.psy.external_server.result.ResultEnum;
import com.sleep.psy.external_server.result.ResultUtil;
import com.sleep.psy.external_server.utils.DateUtils;
import com.sleep.psy.external_server.utils.sign.Md5Utils;
import org.apache.commons.lang3.StringUtils;
import org.redisson.misc.Hash;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author wenliguo
 * @since 2025-08-12
 */
@Service
public class MainUserServiceImpl extends ServiceImpl<MainUserMapper, MainUser> implements MainUserService {

    protected Logger logger = LoggerFactory.getLogger(MainUserService.class);

    @Autowired
    private MainUserMapper mainUserMapper;

    @Autowired
    private SysDeptService sysDeptService;

    @Autowired
    private MainDistributerMapper mainDistributerMapper;

    @Autowired
    private MainUserSchemeService mainUserSchemeService;

    @Autowired
    private MainSchemeService mainSchemeService;

    @Autowired
    private MainUserTypeService mainUserTypeService;

    @Autowired
    private MainUserSchemeMapper userSchemeMapper;

    @Autowired
    private PsyBaseVideoService psyBaseVideoService;

    @Autowired
    private ResourseScaleService resourseScaleService;

    @Autowired
    private ResourseScaleMapper resourseScaleMapper;

    @Autowired
    private EvaluationReportService reportService;


    /**
     * 用户登陆
     * @param req 请求信息
     * @return com.sleep.psy.external_server.result.Result
     * @author wenliguo
     * @date 2025/8/12 11:06
     */
    @Override
    public Result login(LoginReq req) {
        String accountId = req.getAccountId();
        String password = req.getPassword();

        MainUser mainUser = selectByAccountId(accountId);
        if (null == mainUser) {
            return ResultUtil.error(ResultEnum.USER_NOT_EXIST);
        }

        String userPassword = mainUser.getPassword();
        if (!userPassword.equals(Md5Utils.hash(password))) {
            return ResultUtil.error(ResultEnum.USER_PASSWORD_ERROR);
        }


        if (MySqlConstant.STATUS_0.equals(mainUser.getStatus())) {
            return ResultUtil.error(ResultEnum.USER_STATUS_ERROR);
        }

        SysDept dept = sysDeptService.selectDept(mainUser.getId());
        if (null != dept) {
            mainUser.setDeptName(dept.getDeptName());
        }

        return ResultUtil.success(mainUser);

    }



    /**
     * 更新用户信息
     * @author wenliguo
     * @date 2025/8/12 11:41
     * @param req 请求信息
     * @return com.sleep.psy.external_server.result.Result
     */
    @Override
    public Result updateUser(UpdateUserReq req) {
        Long id = req.getId();
        MainUser user = mainUserMapper.selectById(id);
        if (null == user) {
            return ResultUtil.error(ResultEnum.USER_NOT_EXIST);
        }

        MainUser mainUser = new MainUser();
        mainUser.setId(id);
        if (null != req.getUserName()) {
            mainUser.setUserName(req.getUserName());
        }

        if (null != req.getPassword()) {
            mainUser.setPassword(Md5Utils.hash(req.getPassword()));
        }

        if (null != req.getAvatar()) {
            mainUser.setAvatar(req.getAvatar());
        }

        if (null != req.getSex()) {
            mainUser.setSex(req.getSex());
        }

        if (null != req.getBirthday()) {
            mainUser.setBirthday(req.getBirthday());
        }

        if (null != req.getNationality()) {
            mainUser.setNationality(req.getNationality());
        }

        if (null != req.getNativePlace()) {
            mainUser.setNativePlace(req.getNativePlace());
        }

        mainUserMapper.updateById(mainUser);

        return ResultUtil.success(mainUserMapper.selectById(id));
    }

    /**
     * 通过账号密码查询用户
     * @author wenliguo
     * @date 2025/8/12 11:02
     * @param accountId 用户名
     * @param password 密码
     * @return com.sleep.psy.external_server.main.entity.MainUser
     */
    @Override
    public MainUser selectByAccountIdPassword(String accountId, String password) {
        QueryWrapper<MainUser> wrapper = new QueryWrapper<>();
        wrapper.eq("account_id", accountId)
                .eq("password", Md5Utils.hash(password));
        return mainUserMapper.selectOne(wrapper);
    }

    /**
     * 通过账号查询用户
     * @author wenliguo
     * @date 2025/8/12 14:07
     * @param accountId 账号
     * @return com.sleep.psy.external_server.main.entity.MainUser
     */
    @Override
    public MainUser selectByAccountId(String accountId) {
        QueryWrapper<MainUser> wrapper = new QueryWrapper<>();
        wrapper.eq("account_id", accountId);
        return mainUserMapper.selectOne(wrapper);
    }

    /**
     * 注册
     * @author wenliguo
     * @date 2025/8/12 14:20
     * @param req 请求信息
     * @return com.sleep.psy.external_server.result.Result
     */
    @Override
    public Result registUser(RegistReq req) {
        MainUser user = selectByAccountId(req.getAccountId());
        if (null != user) {
            return ResultUtil.error(ResultEnum.USER_EXIST);
        }

        MainUser mainUser = new MainUser();
        mainUser.setAccountId(req.getAccountId());
        mainUser.setPassword(Md5Utils.hash(req.getPassword()));
        mainUserMapper.insert(mainUser);


        MainDistributer distributer = new MainDistributer();
        distributer.setUserId(mainUser.getId());
        distributer.setRealAccountId(req.getDoctorId());
        mainDistributerMapper.insert(distributer);

        Integer schemeId = req.getSchemeId();
        MainScheme scheme = mainSchemeService.selectById(schemeId);
        if (null != scheme) {
            MainUserScheme userScheme = new MainUserScheme();
            if (null != scheme.getStartDate()) {
                userScheme.setSendStartTime(scheme.getStartDate());
            }
            if (null != scheme.getEndDate()) {
                userScheme.setSendEndTime(scheme.getEndDate());
            }
            userScheme.setMainSchemeId(schemeId);

            String info = scheme.getSchemeInfo();
            SchemeInfo schemeInfo = JSONObject.parseObject(info, SchemeInfo.class);
            schemeInfo.getTraining().setSleepControl(null);

            userScheme.setSchemeInfo(JSON.toJSONString(schemeInfo, SerializerFeature.WriteMapNullValue));
            userScheme.setMainUserIds(mainUser.getId() + "");
            mainUserSchemeService.addScheme(userScheme);
        }


        return ResultUtil.success(mainUser);

    }

    /**
     * 通过用户id获取用户信息
     * @author wenliguo
     * @date 2025/8/12 14:25
     * @param userId 用户id
     * @return com.sleep.psy.external_server.result.Result
     */
    @Override
    public Result selectByUserId(Long userId) {
        MainUser user = mainUserMapper.selectById(userId);
        if (null == user) {
            return ResultUtil.error(ResultEnum.USER_NOT_EXIST);
        }

        if (MySqlConstant.STATUS_0.equals(user.getStatus())) {
            return ResultUtil.error(ResultEnum.USER_STATUS_ERROR);
        }

        SysDept dept = sysDeptService.selectDept(user.getId());
        if (null != dept) {
            user.setDeptName(dept.getDeptName());
        }
        return ResultUtil.success(user);
    }

    /**
     * 通过用户id获取用户信息
     * @author wenliguo
     * @date 2025/8/12 14:45
     * @param userId 用户id
     * @return com.sleep.psy.external_server.main.entity.MainUser
     */
    @Override
    public MainUser selectById(Long userId) {
        return mainUserMapper.selectById(userId);
    }

    /**
     * 获取用户的全部方案详情
     * @author wenliguo
     * @date 2025/8/13 14:57
     * @param userId 用户id
     * @return java.util.HashMap<java.lang.String,java.lang.Object>
     */
    @Override
    public Result selectUserScheme(Long userId) {
        QueryWrapper<MainUserScheme> wrapper = new QueryWrapper<>();
        wrapper.eq("main_user_ids", userId)
                .eq("is_del", MySqlConstant.IS_DEL_0)
                .eq("status", MySqlConstant.STATUS_1)
                .orderByDesc("update_time");

        List<MainUserScheme> schemes = userSchemeMapper.selectList(wrapper);
        Date date = new Date();
        if (schemes.isEmpty()) {
            return ResultUtil.error(ResultEnum.NO_SCHEME);

        }

        HashMap<String, Object> map = new HashMap<>();
        map.put("scaleList", new ArrayList<>());
        map.put("audioList", new ArrayList<>());
        map.put("videoList", new ArrayList<>());
        map.put("sleepHeathVideoList", new ArrayList<>());
        map.put("advice","");
        map.put("sleepControl","");
        String advice = "";
        String sleepControl = "";

        //睡眠卫生
        HashSet<PsyBaseVideo> sleepHeathVideoSet = new HashSet<>();
        //视频
        HashSet<PsyBaseVideo> baseVideosSet = new HashSet<>();
        //音频
        HashSet<PsyBaseVideo> videosSet = new HashSet<>();
        //量表
        HashSet<ResourseScale> scalesSet = new HashSet<>();

        MainUserScheme validScheme = schemes.get(0);
        String schemeInfo = validScheme.getSchemeInfo();

        SchemeInfo info = JSONObject.parseObject(schemeInfo, SchemeInfo.class);

        Integer status = info.getStatus();
        if (MySqlConstant.STATUS_0.equals(status)) {
            logger.info("用户方案状态不可用");
            return ResultUtil.success();
        }
        String startDate = info.getStartDate();
        if (null != startDate) {
            Date sDate = DateUtils.stringToDate(startDate, DateUtils.DATE_FORMAT);
            if (date.before(sDate)) {
                logger.info("方案还未到开始时间,用户方案id:{}", validScheme.getId());
                return ResultUtil.success();
            }
        }

        advice = info.getAdvice();
        String scaleIds = info.getEvaluation();
        Training training = info.getTraining();
        String videoIds = training.getSleepTraining();
        String audioIds = training.getMoodDepress();
        String sleepHeath = training.getSleepHeath();
        sleepControl = training.getSleepControl();

        if (StringUtils.isNotBlank(sleepHeath)) {
            if (sleepHeath.contains(",")) {
                String[] split = sleepHeath.split(",");
                for (String s : split) {
                    PsyBaseVideo video = psyBaseVideoService.selectById(Integer.parseInt(s));
                    if (null != video) {
                        sleepHeathVideoSet.add(video);
                    }
                }
            } else {
                PsyBaseVideo video = psyBaseVideoService.selectById(Integer.parseInt(sleepHeath));
                if (null != video) {
                    sleepHeathVideoSet.add(video);
                }
            }
        }

        if (StringUtils.isNotBlank(videoIds)) {
            if (videoIds.contains(",")) {
                String[] split = videoIds.split(",");
                for (String s : split) {
                    PsyBaseVideo video = psyBaseVideoService.selectById(Integer.parseInt(s));
                    if (null != video) {
                        baseVideosSet.add(video);
                    }
                }
            } else {
                PsyBaseVideo video = psyBaseVideoService.selectById(Integer.parseInt(videoIds));
                if (null != video) {
                    baseVideosSet.add(video);
                }
            }

        }

        if (StringUtils.isNotBlank(audioIds)) {
            if (audioIds.contains(",")) {
                String[] split = audioIds.split(",");
                for (String s : split) {
                    PsyBaseVideo video = psyBaseVideoService.selectById(Integer.parseInt(s));
                    if (null != video) {
                        videosSet.add(video);
                    }
                }
            } else {
                PsyBaseVideo video = psyBaseVideoService.selectById(Integer.parseInt(audioIds));
                if (null != video) {
                    videosSet.add(video);
                }
            }

        }

        if (StringUtils.isNotBlank(scaleIds)) {
            if (scaleIds.contains(",")) {

                String[] split = scaleIds.split(",");
                for (String s : split) {
                    ResourseScale scale = resourseScaleMapper.selectById(Integer.parseInt(s));
                    if (null != scale) {
                        scalesSet.add(scale);
                    }
                }

            } else {
                ResourseScale scale = resourseScaleMapper.selectById(Integer.parseInt(scaleIds));
                if (null != scale) {
                    scalesSet.add(scale);
                }
            }
        }

        map.put("schemeId", validScheme.getMainSchemeId());
        map.put("videoList", baseVideosSet);
        map.put("audioList", videosSet);
        map.put("scaleList", scalesSet);
        map.put("advice", advice);
        map.put("sleepControl", sleepControl);
        map.put("sleepHeathVideoList", sleepHeathVideoSet);
        return ResultUtil.success(map);
    }

    @Override
    public Result selectTrainingReport(Long userId) {
        return null;
    }
}
